#include <string.h>
#include <unistd.h>
#include <hwicodec_common.h>

//int deadzone[4] = {0x00000015, 0x0000000b, 0x00000015, 0x0000000b /*deadzone[4]*/};

int hwicodec_pf_h265e_init_bpool(hwicodec_t *h, hwicodec_soc_binfo_t *pbinfo)
{
	int rdnum = 0, encnum = 0, bsnum = 0, dmanum = 0, extnum = 0,  ncunum = 0;
	int y_rdsize = 0, y_encsize = 0, bssize = 0, dmasize = 0, y_extsize = 0, y_ncusize = 0;

	hwicodec_h265e_param_t *param = &h->param.param.h265e_param;
	hwicodec_soc_bpool_t *bpool = &h->soc.bpool;
	int width = C_ALIGN(param->i_width, 16);
	int height = C_ALIGN(param->i_height, 16);
	hwicodec_mmcut_t mmcut[C_CHN_NUM_MAX * C_VB_NUM_MAX];
	int mcidx = 0, i = 0;

	bpool->vb_num = C_SOC_VB_MAX;
	bpool->vbinfo[C_SOC_VB_RD].type = C_SOC_VB_RD;
	rdnum = bpool->vbinfo[C_SOC_VB_RD].num = h->param.param.h265e_param.i_req_rdnum;
	bpool->vbinfo[C_SOC_VB_ENC].type = C_SOC_VB_ENC;
	encnum = bpool->vbinfo[C_SOC_VB_ENC].num = 0;
	bpool->vbinfo[C_SOC_VB_BS].type = C_SOC_VB_BS;
	bsnum = bpool->vbinfo[C_SOC_VB_BS].num = param->i_threads;
	bpool->vbinfo[C_SOC_VB_DMA].type = C_SOC_VB_DMA;
	dmanum = bpool->vbinfo[C_SOC_VB_DMA].num = param->i_threads;
	bpool->vbinfo[C_SOC_VB_EXT].type = C_SOC_VB_EXT;
	extnum = bpool->vbinfo[C_SOC_VB_EXT].num = 0;
	bpool->vbinfo[C_SOC_VB_NCU].type = C_SOC_VB_NCU;
	ncunum = bpool->vbinfo[C_SOC_VB_NCU].num = 0;
	bpool->buf_num = rdnum + encnum + bsnum + dmanum + extnum + ncunum;

	y_rdsize = hwicodec_cal_bufsize(h, &pbinfo[C_SOC_VB_RD], width, height);
#ifndef CONFIG_SINGLE_BS
    bssize = hwicodec_cal_bufsize(h, &pbinfo[C_SOC_VB_BS], width, height);
#endif
	dmasize = hwicodec_cal_bufsize(h, &pbinfo[C_SOC_VB_DMA], width, height);
	bpool->buf_size = (y_rdsize*3/2+C_VB_ALIGN)*rdnum+(y_encsize*3/2+C_VB_ALIGN)*encnum+bssize*bsnum+dmasize*dmanum+(y_extsize*3/2+C_VB_ALIGN)*extnum + ncunum * y_ncusize;

	if ((bpool->buf_base_v = (intptr_t)h->param.ckmalloc(bpool->buf_size, C_VB_ALIGN)) == 0) {
		hwicodec_log(h, C_LOG_ERROR, "malloc buf_base size:%d failed\n", bpool->buf_size);
		goto err_malloc_buf_base;
	}

	memset(mmcut, 0, sizeof(hwicodec_mmcut_t));
	for (i = 0; i < rdnum; i++, mcidx++) {
		mmcut[mcidx].type = C_SOC_VB_RD;
		mmcut[mcidx].size = c_align(y_rdsize * 3 / 2, pbinfo[C_SOC_VB_RD].align, pbinfo[C_SOC_VB_RD].disalign);
		mmcut[mcidx].ysize = y_rdsize;
	}

	for (i = 0; i < encnum; i++, mcidx++) {
		mmcut[mcidx].type = C_SOC_VB_ENC;
		mmcut[mcidx].size = c_align(y_encsize * 3 / 2, pbinfo[C_SOC_VB_ENC].align, pbinfo[C_SOC_VB_ENC].disalign);
		mmcut[mcidx].ysize = y_encsize;
	}

	for (i = 0; i < bsnum; i++, mcidx++) {
		mmcut[mcidx].type = C_SOC_VB_BS;
		mmcut[mcidx].size = bssize;
		mmcut[mcidx].ysize = 0;
	}

	for (i = 0; i < dmanum; i++, mcidx++) {
		mmcut[mcidx].type = C_SOC_VB_DMA;
		mmcut[mcidx].size = dmasize;
		mmcut[mcidx].ysize = 0;
	}

	for (i = 0; i < extnum; i++, mcidx++) {
		mmcut[mcidx].type = C_SOC_VB_EXT;
		mmcut[mcidx].size = c_align(y_extsize * 3 / 2, pbinfo[C_SOC_VB_EXT].align, pbinfo[C_SOC_VB_EXT].disalign);
		mmcut[mcidx].ysize = y_extsize;
	}

	for (i = 0; i < ncunum; i++, mcidx++) {
		mmcut[mcidx].type = C_SOC_VB_NCU;
		mmcut[mcidx].size = y_ncusize;
		mmcut[mcidx].ysize = 0;
	}

	if (mcidx != bpool->buf_num) {
		hwicodec_log(h, C_LOG_ERROR, "mcidx err\n");
		goto err_mcidx;
	}

	if(hwicodec_init_soc_bpool(h, pbinfo, mmcut, width, height, 0) < 0) {
		hwicodec_log(h, C_LOG_ERROR, "init_soc_bpool\n");
		goto err_init_soc_bpool;
	}

	return 0;

err_init_soc_bpool:
err_mcidx:
	h->param.ckfree((void *)bpool->buf_base_v);
err_malloc_buf_base:
	return -1;
}
